package com.heima.search.service.impl;

import com.heima.article.feign.ApArticleFeign;
import com.heima.common.constants.MQConstants;
import com.heima.common.dtos.Result;
import com.heima.common.exception.AppHttpCodeEnum;
import com.heima.common.exception.LeadNewsException;
import com.heima.model.article.pojos.ApArticle;
import com.heima.model.search.dtos.UserSearchDto;
import com.heima.model.search.pojos.ArticleDocument;
import com.heima.model.user.pojos.ApUser;
import com.heima.search.repository.ArticleDocumentRepository;
import com.heima.search.service.ArticleSeachService;
import com.heima.utils.common.BeanHelper;
import com.heima.utils.common.JsonUtils;
import com.heima.utils.common.ThreadLocalUtils;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.sort.SortBuilders;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
import org.springframework.data.elasticsearch.core.SearchHit;
import org.springframework.data.elasticsearch.core.SearchHits;
import org.springframework.data.elasticsearch.core.query.NativeSearchQuery;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

@Service
public class ArticleSeachServiceImpl implements ArticleSeachService {
    @Autowired
    private ElasticsearchRestTemplate restTemplate;
    @Autowired
    private ApArticleFeign apArticleFeign;
    @Autowired
    private ArticleDocumentRepository articleDocumentRe;
    @Autowired
    private KafkaTemplate kafkaTemplate;

    @Override
    public Result<List<ArticleDocument>> articleSearch(UserSearchDto dto) {
        if (dto.getPageNum() == 0) {
            dto.setPageNum(1);
        }
        if (dto.getPageSize() == 0) {
            dto.setPageSize(20);
        }
        try {
            //1.封装条件
            //1）创建查询构造器对象: 用于封装条件
            NativeSearchQueryBuilder builder = new NativeSearchQueryBuilder();
            builder.withQuery(QueryBuilders.matchQuery("title", dto.getSearchWords()));
            //添加分页条件
            /**
             * 参数一：页码，从0开始计算
             * 参数二：页面大小
             */
            builder.withPageable(PageRequest.of(dto.getPageNum() - 1, dto.getPageSize()));
            //添加排序条件
            builder.withSort(SortBuilders.fieldSort("publishTime").order(SortOrder.DESC));
            //3）使用查询构造器构造查询对象
            NativeSearchQuery searchQuery = builder.build();

            SearchHits<ArticleDocument> searchHits = restTemplate.search(searchQuery, ArticleDocument.class);

            List<ArticleDocument> list = new ArrayList<>();
            for (SearchHit<ArticleDocument> hit : searchHits) {

                ArticleDocument content = hit.getContent();
                list.add(content);
            }
            //获取大登录用户
            Integer userId = null;
            ApUser apUser = (ApUser) ThreadLocalUtils.get();
            if (apUser != null){
                userId = apUser.getId();
            }
            //同步记录用户搜索数据
            HashMap<String, Object> msgMap = new HashMap<>();
            msgMap.put("userId",userId);
            msgMap.put("equimentId",dto.getEquipmentId());
            msgMap.put("keyword",dto.getSearchWords());
            kafkaTemplate.send(MQConstants.USER_SEARCH_TOPIC, JsonUtils.toString(msgMap));

            return Result.ok(list);
        } catch (Exception e) {
            e.printStackTrace();
            throw new LeadNewsException(AppHttpCodeEnum.SERVER_ERROR);
        }
    }
    /**
     * 文章索引库同步监听
     */
    @Override
    public void saveToES(Long articleId) {
        ApArticle apArticle = apArticleFeign.findById(articleId);

        ArticleDocument articleDocument = BeanHelper.copyProperties(apArticle, ArticleDocument.class);
        articleDocumentRe.save(articleDocument);


    }

    @Override
    public void removeFromES(Long articleId) {
        articleDocumentRe.deleteById(articleId);
    }

    @Override
    public Result<List<ArticleDocument>> search(UserSearchDto dto) {
        return null;
    }
}
